/**
 * 
 */
package com.laozhao.dreamframe.dbmanager;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * @author LaoZhao
 *
 */
public class DataSource extends AbstractDataSource {
	private transient Log log = LogFactory.getLog(this.getClass());
	//读入XML
	private FileInputStream inputStream;

//	public DreamDataSource(){
//		String fileName = ".\\data";
//	}
	/**
	 * @param fileName
	 * @throws IOException 
	 * @throws SAXException 
	 * @throws ParserConfigurationException 
	 */
	public DataSource(String fileName) throws ParserConfigurationException, SAXException, IOException {
		super(fileName);
		this.inputStream = new FileInputStream(new File(fileName));
		readXML();
	}

	/**
	 * @param file
	 * @throws IOException 
	 * @throws SAXException 
	 * @throws ParserConfigurationException 
	 */
	public DataSource(File file) throws ParserConfigurationException, SAXException, IOException {
		super(file);
		this.inputStream = new FileInputStream(file);
		readXML();
	}

	/**
	 * @param inputStream
	 * @throws IOException 
	 * @throws SAXException 
	 * @throws ParserConfigurationException 
	 */
	public DataSource(FileInputStream inputStream) throws ParserConfigurationException, SAXException, IOException {
		super(inputStream);
		this.inputStream = inputStream;
		readXML();
	}

	/**
	 * 读取文件内容，放置进beans
	 * @throws ParserConfigurationException 
	 * @throws IOException 
	 * @throws SAXException 
	 */
	private void readXML() throws ParserConfigurationException, SAXException, IOException{
		DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = dFactory.newDocumentBuilder();
		
		// 获得Document对象的实例
		Document dom = builder.parse(inputStream);
		// 获得根节点
		Element root = dom.getDocumentElement();
		//读取根节点属性
		if(root != null && this.getData_sourceNodeName().equals(root.getNodeName())){
			//读取并设置"data_source"节点的内容
			if(!getRootAttribute(root)){
				return;
			}
			//读取子节点的内容
			if(root.hasChildNodes()){
				//读取并设置"server"节点的内容
//				NodeList nodeList = root.getChildNodes();
				if(!getServerAttribute(root)){
					return;
				}
				
				//读取并设置"login"节点的内容
				if(!getLoginAttribute(root)){
					return;
				}
				//读取并设置"transaction"节点的内容
				if(!getTransactionAttribute(root)){
					return;
				}
				//读取并设置"pooling"节点的内容
				if(!getPoolingAttribute(root)){
					return;
				}
				//读取子节点的内容
				Element poolNoot = (Element)root.getElementsByTagName(this.getPoolingNodeName()).item(0);
				if(poolNoot.hasChildNodes()){
					//读取并设置"capacity"节点的内容
					if(!getCapacityAttribute(poolNoot)){
						return;
					}
					//读取并设置"retrying"节点的内容
					if(!getRetryingAttribute(poolNoot)){
						return;
					}
					//读取并设置"testing"节点的内容
					if(!getTestingAttribute(poolNoot)){
						return;
					}
					//读取并设置"shrinking"节点的内容
					if(!getShrinkingAttribute(poolNoot)){
						return;
					}
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no "+this.getPoolingNodeName()+" childrens \n");
				}
			}else{
				log.error("\n" + "^_^ XML format error! \n the file has no  childrens \n");
			}
		}else{
			log.error("\n" + "^_^ XML format error! \n the file root is not exit or not named :" + this.getData_sourceNodeName()+"\n");
		}
	}
	
	
	//读取并设置"data_source"节点的内容
	private boolean getRootAttribute(Element root){
		if(root.hasAttribute(this.getSourceNameKey())){
			this.setSourceNameValue(root.getAttribute(this.getSourceNameKey()));
		}else{
			log.error("\n" + "^_^ XML format error! \n the file has no  attributes named : "+this.getSourceNameKey()+" \n");
			return false;
		}
		if(root.hasAttribute(this.getSourceDbTypeNameKey())){
			this.setSourceDbTypeNameValue(root.getAttribute(this.getSourceDbTypeNameKey()));
		}else{
			log.error("\n" + "^_^ XML format error! \n the file has no  attributes named : "+this.getSourceDbTypeNameKey()+" \n");
			return false;
		}
		return true;
	}
	//读取并设置"server"节点的内容
	private boolean getServerAttribute(Element root){
		if(root.getElementsByTagName(this.getServerNodeName()) != null){
			NodeList serverNodeList = root.getElementsByTagName(this.getServerNodeName());
			if(serverNodeList.item(0) != null){
				Element serverNoot = (Element)serverNodeList.item(0);
				if(serverNoot.hasAttribute(this.getServerNameKey())){
					this.setServerNameValue(serverNoot.getAttribute(this.getServerNameKey()));
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no  attributes named : "+this.getServerNameKey()+" \n");
					return false;
				}
				if(serverNoot.hasAttribute(this.getserverPortKey())){
					this.setserverPortValue(serverNoot.getAttribute(this.getserverPortKey()));
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no attributes named : "+this.getserverPortKey()+" \n");
					return false;
				}
				if(serverNoot.hasAttribute(this.getserverDatabaseNameKey())){
					this.setserverDatabaseNameValue(serverNoot.getAttribute(this.getserverDatabaseNameKey()));
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no attributes named : "+this.getserverDatabaseNameKey()+" \n");
					return false;
				}
			}else{
				log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getServerNodeName()+" \n");
				return false;
			}
		}else{
			log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getServerNodeName()+" \n");
			return false;
		}
		return true;
	}
	

	//读取并设置"login"节点的内容
	private boolean getLoginAttribute(Element root) {
		if(root.getElementsByTagName(this.getLoginNodeName()) != null){
			NodeList loginNodeList = root.getElementsByTagName(this.getLoginNodeName());
			if(loginNodeList.item(0) != null){
				Element loginrNoot = (Element)loginNodeList.item(0);
				if(loginrNoot.hasAttribute(this.getSrcKey())){
					this.setSrcValue(loginrNoot.getAttribute(this.getSrcKey()));
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no  attributes named : "+this.getSrcKey()+" \n");
					return false;
				}
				if(loginrNoot.hasAttribute(this.getUrlKey())){
					this.setUrlValue(loginrNoot.getAttribute(this.getUrlKey()));
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no attributes named : "+this.getUrlKey()+" \n");
					return false;
				}
				if(loginrNoot.hasAttribute(this.getUsrKey())){
					this.setUsrValue(loginrNoot.getAttribute(this.getUsrKey()));
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no attributes named : "+this.getUsrKey()+" \n");
					return false;
				}
				if(loginrNoot.hasAttribute(this.getPwdKey())){
					this.setPwdValue(loginrNoot.getAttribute(this.getPwdKey()));
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no attributes named : "+this.getPwdKey()+" \n");
					return false;
				}
			}else{
				log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getLoginNodeName()+" \n");
				return false;
			}
		}else{
			log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getLoginNodeName()+" \n");
			return false;
		}
		return true;
	}
	

	//读取并设置"transaction"节点的内容
	private boolean getTransactionAttribute(Element root) {
		if(root.getElementsByTagName(this.getTransactionNodeName()) != null){
			NodeList tranNodeList = root.getElementsByTagName(this.getTransactionNodeName());
			if(tranNodeList.item(0) != null){
				Element tranrNoot = (Element)tranNodeList.item(0);
				if(tranrNoot.hasAttribute(this.getAutoCommitKey())){
					if("true".equals(tranrNoot.getAttribute(this.getAutoCommitKey()))){
						this.setAutoCommitValue(true);
					}
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no  attributes  named : "+this.getAutoCommitKey()+" \n");
					return false;
				}
				
			}else{
				log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getTransactionNodeName()+" \n");
				return false;
			}
		}else{
			log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getTransactionNodeName()+" \n");
			return false;
		}
		return true;
	}
	
	//读取并设置"pooling"节点的内容
	private boolean getPoolingAttribute(Element root) {
		if(root.getElementsByTagName(this.getPoolingNodeName()) != null){
			NodeList poolNodeList = root.getElementsByTagName(this.getPoolingNodeName());
			if(poolNodeList.item(0) != null){
				Element poolNoot = (Element)poolNodeList.item(0);
				if(poolNoot.hasAttribute(this.getPoolEnableKey())){
					if("true".equals(poolNoot.getAttribute(this.getPoolEnableKey()))){
						this.setPoolEnableValue(true);
					}
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no  attributes  named : "+this.getPoolEnableKey()+" \n");
					return false;
				}
				
			}else{
				log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getPoolingNodeName()+" \n");
				return false;
			}
		}else{
			log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getPoolingNodeName()+" \n");
			return false;
		}
		return true;
	}
	

	//读取并设置"capacity"节点的内容
	private boolean getCapacityAttribute(Element poolNoot) {
		if(poolNoot.getElementsByTagName(this.getCapacityNodeName()) != null){
			NodeList capNodeList = poolNoot.getElementsByTagName(this.getCapacityNodeName());
			if(capNodeList.item(0) != null){
				Element capNoot = (Element)capNodeList.item(0);
				if(capNoot.hasAttribute(this.getCapMaxKey())){
					this.setCapMaxValue(Integer.valueOf(capNoot.getAttribute(this.getCapMaxKey())));
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no  attributes named : "+this.getCapMaxKey()+" \n");
					return false;
				}
				if(capNoot.hasAttribute(this.getCapInitKey())){
					this.setCapInitValue(Integer.valueOf(capNoot.getAttribute(this.getCapInitKey())));
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no attributes named : "+this.getCapInitKey()+" \n");
					return false;
				}
			}else{
				log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getCapacityNodeName()+" \n");
				return false;
			}
		}else{
			log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getCapacityNodeName()+" \n");
			return false;
		}
		return true;
	}

	

	//读取并设置"retrying"节点的内容
	private boolean getRetryingAttribute(Element poolNoot) {
		if(poolNoot.getElementsByTagName(this.getRetryingNodeName()) != null){
			NodeList retryNodeList = poolNoot.getElementsByTagName(this.getRetryingNodeName());
			if(retryNodeList.item(0) != null){
				Element retryNoot = (Element)retryNodeList.item(0);
				if(retryNoot.hasAttribute(this.getRetryTimesKey())){
					this.setRetryTimesValue(Integer.valueOf(retryNoot.getAttribute(this.getRetryTimesKey())));
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no  attributes named : "+this.getRetryTimesKey()+" \n");
					return false;
				}
				if(retryNoot.hasAttribute(this.getRetryIntervalKey())){
					this.setRetryIntervalValue(Integer.valueOf(retryNoot.getAttribute(this.getRetryIntervalKey())));
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no attributes named : "+this.getRetryIntervalKey()+" \n");
					return false;
				}
			}else{
				log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getRetryingNodeName()+" \n");
				return false;
			}
		}else{
			log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getRetryingNodeName()+" \n");
			return false;
		}
		return true;
	}
	
	

	//读取并设置"testing"节点的内容
	private boolean getTestingAttribute(Element poolNoot) {
		if(poolNoot.getElementsByTagName(this.getTestingNodeName()) != null){
			NodeList testNodeList = poolNoot.getElementsByTagName(this.getTestingNodeName());
			if(testNodeList.item(0) != null){
				Element testNoot = (Element)testNodeList.item(0);
				if(testNoot.hasAttribute(this.getTestEnableKey())){
					if("true".equals(testNoot.getAttribute(this.getTestEnableKey()))){
						this.setTestEnableValue(true);
					}
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no attributes named : "+this.getTestEnableKey()+" \n");
					return false;
				}
			}else{
				log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getTestingNodeName()+" \n");
				return false;
			}
		}else{
			log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getTestingNodeName()+" \n");
			return false;
		}
		return true;
	}
	
	//读取并设置"shrinking"节点的内容
	private boolean getShrinkingAttribute(Element poolNoot) {
		if(poolNoot.getElementsByTagName(this.getShrinkingNodeName()) != null){
			NodeList shkNodeList = poolNoot.getElementsByTagName(this.getShrinkingNodeName());
			if(shkNodeList.item(0) != null){
				Element shkNoot = (Element)shkNodeList.item(0);
				if(shkNoot.hasAttribute(this.getShrinkEnableKey())){
					if("true".equals(shkNoot.getAttribute(this.getShrinkEnableKey()))){
						this.setShrinkEnableValue(true);
					}
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no attributes named : "+this.getShrinkEnableKey()+" \n");
					return false;
				}
				if(shkNoot.hasAttribute(this.getShrinkIntervalKey())){
					this.setShrinkIntervalValue(Integer.valueOf(shkNoot.getAttribute(this.getShrinkIntervalKey())));
				}else{
					log.error("\n" + "^_^ XML format error! \n the file has no attributes named : "+this.getShrinkIntervalKey()+" \n");
					return false;
				}
			}else{
				log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getShrinkingNodeName()+" \n");
				return false;
			}
		}else{
			log.error("\n" + "^_^ XML format error! \n the file has no children named : "+this.getShrinkingNodeName()+" \n");
			return false;
		}
		return true;
	}

}
